home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / gemfsc20 / gemfsc20.lzh / FRMPROGR.C < prev    next >
C/C++ Source or Header  |  1993-03-28  |  14KB  |  429 lines

  1.  
  2. /*************************************************************************
  3.  * FRMDSMEN.C - The frm_dsmenu() routine.
  4.  *************************************************************************/
  5.  
  6. #include "gemfintl.h"
  7. #include <osbind.h>
  8.  
  9. /*-------------------------------------------------------------------------
  10.  * The tedinfos for the dialog body text.
  11.  *     We have to use our own tedinfos instead of sharing the common array
  12.  *     of them in FRMNLDSU.C, because we're non-modal, and other users of
  13.  *     the common array can be invoked while the progress display is up.
  14.  *-----------------------------------------------------------------------*/
  15.  
  16. static TEDINFO GFAR local_tedinfos[] = {
  17.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  18.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  19.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  20.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  21.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  22.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  23.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  24.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  25.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1},
  26.   {NULL, NULL, NULL, 3, 6, 0, 0x11F0, 0,  0,   1,    1}
  27. };
  28.  
  29. /*------------------------------------------------------------------------
  30.  * the dialog tree...
  31.  *-----------------------------------------------------------------------*/
  32.  
  33. #define OUTLINED_BOX_SPEC 0x00021100L
  34. #define SHADOWED_BOX_SPEC 0x00FF1100L
  35.  
  36. static OBJECT GFAR progress_dialog[] = {
  37.  { -1,    1, 13, G_BOX,       NONE,       OUTLINED, (_Ob_spec_t)0x00021100L, 0x0000, 0x0000, 0x0001, 0x0000},
  38.  { 12,    2, 11, G_IBOX,       NONE,       NORMAL,     (_Ob_spec_t)0x00001100L, 0x0001, 0x0000, 0x0001, 0x0000},
  39.  {    3, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0001, 0x0001, 0x0001},
  40.  {    4, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0002, 0x0001, 0x0001},
  41.  {    5, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0003, 0x0001, 0x0001},
  42.  {    6, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0004, 0x0001, 0x0001},
  43.  {    7, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0005, 0x0001, 0x0001},
  44.  {    8, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0006, 0x0001, 0x0001},
  45.  {    9, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0007, 0x0001, 0x0001},
  46.  { 10, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0008, 0x0001, 0x0001},
  47.  { 11, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0009, 0x0001, 0x0001},
  48.  {    1, -1, -1, G_BOXTEXT,  NONE,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x000A, 0x0001, 0x0001},
  49.  { 13, -1, -1, G_BOX,       NONE,       NORMAL,     (_Ob_spec_t)0x00FF1131L, 0x0001, 0x0000, 0x0001, 0x0001},
  50.  {    0, -1, -1, G_BUTTON,   0x0027,       NORMAL,     (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001}
  51. };
  52.  
  53. #define TEXT_BOX        1
  54. #define FIRST_TEXT_LINE 2
  55. #define THERMO_BAR        12
  56. #define EXIT_BUTTON     13
  57.  
  58. #define MAXLINES Array_els(local_tedinfos)
  59.  
  60. /*------------------------------------------------------------------------
  61.  * misc static data...
  62.  *-----------------------------------------------------------------------*/
  63.  
  64. static FormControl GFAR progress_ctl;
  65. static short       initdone = FALSE;
  66. static char        *formatted_text;
  67. static short       lastline;
  68. static short       oldmouse;
  69.  
  70. /*------------------------------------------------------------------------
  71.  * dummy_do - The form_do() handler when the dialog isn't abortable.
  72.  *-----------------------------------------------------------------------*/
  73.  
  74. #ifdef GEMFAST_PROTOS
  75.   static short dummy_do(FormControl *ctl)
  76. #else
  77.   static short dummy_do(ctl)
  78.     FormControl *ctl;
  79. #endif
  80. {
  81.     (void)ctl;
  82.     return NO_OBJECT;
  83. }
  84.  
  85. /*------------------------------------------------------------------------
  86.  * watchbutton_do - The form_do() handler to watch the abort button.
  87.  *    This is a non-modal handler.  It checks the keyboard and mouse button,
  88.  *    and if neither is active, it returns NO_OBJECT.
  89.  *-----------------------------------------------------------------------*/
  90.  
  91. #ifdef GEMFAST_PROTOS
  92.   static short watchbutton_do(FormControl *ctl)
  93. #else
  94.   static short watchbutton_do(ctl)
  95.     FormControl *ctl;
  96. #endif
  97. {
  98.     short     obj;
  99.     short     mouseobj;
  100.     XMULTI xm;
  101.  
  102.     xm.mflags     = MU_BUTTON | MU_KEYBD | MU_TIMER;
  103.     xm.mbstate     = 1;
  104.     xm.mbmask     = 1;
  105.     xm.mbclicks  = 1;
  106.     xm.mtcount     = 1;
  107.  
  108.     obj = NO_OBJECT;
  109.     evnx_multi(&xm);
  110.  
  111.     if ((xm.mwhich & MU_KEYBD)
  112.      && (xm.mkreturn & 0x00FF) == '\r') {
  113.         obj = EXIT_BUTTON;
  114.         obj_stchange(ctl->ptree, obj, SELECTED, OBJ_CLIPDRAW, ctl->pboundrect);
  115.     }
  116.  
  117.     if (xm.mwhich & MU_BUTTON) {
  118.         mouseobj = objc_find(ctl->ptree, ROOT, MAX_DEPTH, xm.mmox, xm.mmoy);
  119.         if (mouseobj == NO_OBJECT) {
  120.             Bconout(2, 7); /* ding!                                                   */
  121.         } else if (mouseobj == EXIT_BUTTON) {
  122.             if (graf_watchbox(ctl->ptree, EXIT_BUTTON, SELECTED, NORMAL)) {
  123.                 obj = EXIT_BUTTON;
  124.             }
  125.         } else if (mouseobj == ctl->moverobj) {
  126.             obj = mouseobj;
  127.         }
  128.     }
  129.  
  130.     return obj;
  131. }
  132.  
  133. /*------------------------------------------------------------------------
  134.  * setup_dialog - Construct the dynamic dialog, paint it.
  135.  *-----------------------------------------------------------------------*/
  136.  
  137. #ifdef GEMFAST_PROTOS
  138.   static short setup_dialog(long options, short increments,
  139.                             char *button, char *fmt, va_list args)
  140. #else
  141.   static short setup_dialog(options, increments, button, fmt, args)
  142.     long        options;
  143.     short          increments;
  144.     char       *button;
  145.     char       *fmt;
  146.     va_list     args;
  147. #endif
  148. {
  149.     short               status;
  150.     short               numlines;
  151.     short               maxwidth;
  152.     short               btnwidth;
  153.     short               cumulative_height;
  154.     short               wchar  = gl_wchar;
  155.     short               hchar2 = gl_hchar * 2;
  156.     char            *strptrs[MAXLINES+1];
  157.     char            *strpatches[MAXLINES+1];
  158.     register OBJECT *ptree = progress_dialog;
  159.  
  160.     /*--------------------------------------------------------------------
  161.      * do one-time init, validate parms, merge in default options.
  162.      *-------------------------------------------------------------------*/
  163.  
  164.     if (!initdone) {
  165.         initdone = TRUE;
  166.         rsc_treefix(ptree);
  167.         if (0 != (status = obj_mkthermo(ptree, THERMO_BAR, 1))) {
  168.             return status;
  169.         }
  170.     }
  171.  
  172.     if (progress_ctl.ptree != NULL) {
  173.         return gfErr_resource_in_use;
  174.     }
  175.  
  176.     if (increments >= gl_rwdesk.g_w) {
  177.         return gfErr_parameter_range;
  178.     }
  179.  
  180.     if (!(options & FRM_NODEFAULTS)) {
  181.         options |= _FrmDefaults | (FRM_DEFAULT_DYNOPT & ~FRM_MOUSEARROW);
  182.     }
  183.     options |= FRM_MANDATORY_DYNOPT;
  184.  
  185.     /*--------------------------------------------------------------------
  186.      * if a button was specified, its string is the initial maxwidth.
  187.      *-------------------------------------------------------------------*/
  188.  
  189.     if (button == NULL) {
  190.         maxwidth = btnwidth = 0;
  191.     } else {
  192.         maxwidth = btnwidth = (short)strlen(button) + 2;
  193.     }
  194.  
  195.     /*--------------------------------------------------------------------
  196.      * format the text and load it into the dialog objects.
  197.      * save a pointer to the string pointer for the last text line.
  198.      * this lets easily change the last line of text during an update.
  199.      *-------------------------------------------------------------------*/
  200.  
  201.     formatted_text = _FrmVFormat(fmt, args, NULL);
  202.  
  203.     _FrmNL2DS(formatted_text, strptrs, strpatches, MAXLINES);
  204.     numlines = _FrmDS2Obj(strptrs, &ptree[FIRST_TEXT_LINE], local_tedinfos,
  205.                             &maxwidth, MAXLINES);
  206.  
  207.     lastline = TEXT_BOX + numlines;
  208.  
  209.     /*--------------------------------------------------------------------
  210.      * from this point on, widths are pixels, not characters.  if the
  211.      * thermo bar is wider than the text, it becomes the maxwidth.
  212.      * at this point, maxwidth is the width of the widest text line or
  213.      * the termo bar, but does not include the whitespace gutters on
  214.      * either side of the text/thermo.
  215.      *-------------------------------------------------------------------*/
  216.  
  217.     maxwidth *= wchar;
  218.     btnwidth *= wchar;
  219.  
  220.     if (maxwidth < increments) {
  221.         maxwidth = increments;
  222.     }
  223.  
  224.     /*--------------------------------------------------------------------
  225.      * set the widths of the dialog and 1st-level children.  set the
  226.      * height of the text strings part of the dialog.
  227.      *-------------------------------------------------------------------*/
  228.  
  229.     _FrmTrWidths(ptree, TEXT_BOX,    maxwidth);
  230.     cumulative_height            = numlines * gl_hchar;
  231.     ptree[TEXT_BOX].ob_height    = cumulative_height;
  232.  
  233.     /*--------------------------------------------------------------------
  234.      * if a thermo bar was requested, set it up, else hide it.
  235.      *-------------------------------------------------------------------*/
  236.  
  237.     if (increments > 0) {
  238.         cumulative_height           += hchar2;
  239.         ptree[THERMO_BAR].ob_y        = cumulative_height;
  240.         ptree[THERMO_BAR].ob_width    = maxwidth;
  241.         obj_mkthermo(ptree, THERMO_BAR, increments);
  242.         ptree[THERMO_BAR].ob_flags &= ~HIDETREE;
  243.     } else {
  244.         ptree[THERMO_BAR].ob_flags |= HIDETREE;
  245.     }
  246.  
  247.     /*--------------------------------------------------------------------
  248.      * from this point on, maxwidth includes the 2-char whitespace gutter.
  249.      *-------------------------------------------------------------------*/
  250.  
  251.     maxwidth += 2 * wchar;
  252.  
  253.     /*--------------------------------------------------------------------
  254.      * if a button was specified, set it up, else hide it.
  255.      *-------------------------------------------------------------------*/
  256.  
  257.     if (button != NULL) {
  258.         cumulative_height           += hchar2;
  259.         ptree[EXIT_BUTTON].ob_width = btnwidth;
  260.         ptree[EXIT_BUTTON].ob_y     = cumulative_height;
  261.         ptree[EXIT_BUTTON].ob_x     = (maxwidth - btnwidth) / 2;
  262.         ptree[EXIT_BUTTON].ob_flags &= ~HIDETREE;
  263.         ptree[EXIT_BUTTON]._Ob_spec = (_Ob_spec_t)button;
  264.     } else {
  265.         ptree[EXIT_BUTTON].ob_flags |= HIDETREE;
  266.     }
  267.  
  268.     /*--------------------------------------------------------------------
  269.      * now set the width and height of the overal dialog, and handle the
  270.      * DSHADOWED and DSL1TITLE options.
  271.      *-------------------------------------------------------------------*/
  272.  
  273.     cumulative_height           += hchar2;
  274.     ptree->ob_width             = maxwidth;
  275.     ptree->ob_height            = cumulative_height;;
  276.  
  277.     if (options & FRM_DSHADOWED) {
  278.         ptree->ob_state = SHADOWED;
  279.         ptree->_Ob_spec  = (_Ob_spec_t)SHADOWED_BOX_SPEC;
  280.     } else {
  281.         ptree->ob_state = OUTLINED;
  282.         ptree->_Ob_spec  = (_Ob_spec_t)OUTLINED_BOX_SPEC;
  283.     }
  284.  
  285.     /*--------------------------------------------------------------------
  286.      * grab control of the mouse, then init and paint the dialog.
  287.      * we hold on to the mouse semaphore until the progress dialog is
  288.      * closed, because we (potentially at least) have a screen area
  289.      * saved via blit and we can't allow redraws; also, since we can't
  290.      * respond to redraws and we may be sitting over a window, we can't
  291.      * allow window controls.
  292.      *-------------------------------------------------------------------*/
  293.  
  294.     wind_update(BEG_MCTRL);
  295.     if (options & FRM_MOUSEARROW) {
  296.         oldmouse = graf_mouse(ARROW, NULL);
  297.     } else {
  298.         oldmouse = -1;
  299.     }
  300.  
  301.     {
  302.         register FormControl *ctl = &progress_ctl;
  303.  
  304.         _FrmSetup(ctl, options|FRM_DSTART, ptree, &gl_rwdesk);
  305.         frm_start(ctl);
  306.         frm_draw(ctl, ROOT);
  307.  
  308.         ctl->form_do = (button == NULL) ? dummy_do : watchbutton_do;
  309.     }
  310.  
  311.     return 0;
  312. }
  313.  
  314. /*------------------------------------------------------------------------
  315.  * update_dialog - Update the thermo bar and/or text in the dialog.
  316.  *-----------------------------------------------------------------------*/
  317.  
  318. #ifdef GEMFAST_PROTOS
  319.   static short update_dialog(short new_position, char *fmt, va_list args)
  320. #else
  321.   static short update_dialog(new_position, fmt, args)
  322.     short       new_position;
  323.     char    *fmt;
  324.     va_list  args;
  325. #endif
  326. {
  327.     register FormControl *ctl = &progress_ctl;
  328.     static char GFAR      linebuf[256];
  329.  
  330.     if (ctl->ptree == NULL) {
  331.         return FALSE;
  332.     }
  333.  
  334.     if (fmt != NULL) {
  335.         vsprintf(linebuf, fmt, args);
  336.         rsc_sstrings(ctl->ptree, lastline, linebuf, -1);
  337.         frm_draw(ctl, lastline);
  338.     }
  339.  
  340.     if (new_position != 0) {
  341.         obj_udthermo(ctl->ptree, THERMO_BAR, new_position, ctl->pboundrect);
  342.     }
  343.  
  344.     return (EXIT_BUTTON == frm_do(ctl, ROOT));
  345. }
  346.  
  347. /*------------------------------------------------------------------------
  348.  * cleanup_dialog - Remove dialog from the screen, release resources.
  349.  *-----------------------------------------------------------------------*/
  350.  
  351. #ifdef GEMFAST_PROTOS
  352.   static short cleanup_dialog(void)
  353. #else
  354.   static short cleanup_dialog()
  355. #endif
  356. {
  357.     register FormControl *ctl = &progress_ctl;
  358.  
  359.     if (ctl->ptree != NULL) {
  360.         frm_finish(ctl);
  361.         frm_cleanup(ctl);
  362.         if (oldmouse != -1) {
  363.             graf_mouse(oldmouse, NULL);
  364.         }
  365.         wind_update(END_MCTRL);
  366.         _FrmVFree(formatted_text);
  367.         ctl->ptree = NULL;
  368.     }
  369.     return 0;
  370. }
  371.  
  372. /*------------------------------------------------------------------------
  373.  * frm_progress - Dispatch the various activities for progress reporting.
  374.  *-----------------------------------------------------------------------*/
  375.  
  376. #ifdef GEMFAST_PROTOS
  377.   short frm_vprogress(long options, short increments,
  378.                       char *buttons, char *fmt, va_list args)
  379. #else
  380.   short frm_vprogress(options, increments, buttons, fmt, args)
  381.     long options;
  382.     short  increments;
  383.     char *buttons;
  384.     char *fmt;
  385.     va_list args;
  386. #endif
  387. {
  388.     short      rv;
  389.  
  390.     switch ((options & FRM_ACTIONBITS) >> 16) {
  391.       case FRM_PSTART >> 16:
  392.         rv = setup_dialog(options, increments, buttons, fmt, args);
  393.         break;
  394.       case FRM_PUPDATE >> 16:
  395.         rv = update_dialog(increments, fmt, args);
  396.         break;
  397.       case FRM_PFINISH >> 16:
  398.         rv = cleanup_dialog();
  399.         break;
  400.       default:
  401.         rv = gfErr_action_invalid;
  402.         break;
  403.     }
  404.  
  405.     return rv;
  406. }
  407.  
  408.  
  409. #ifdef GEMFAST_PROTOS
  410.   short frm_progress(long options, short increments,
  411.                      char *buttons, char *fmt, ...)
  412. #else
  413.   short frm_progress(options, increments, buttons, fmt)
  414.     long options;
  415.     short  increments;
  416.     char *buttons;
  417.     char *fmt;
  418. #endif
  419. {
  420.     va_list args;
  421.     short    rv;
  422.  
  423.     va_start(args, fmt);
  424.     rv = frm_vprogress(options, increments, buttons, fmt, args);
  425.     va_end(args);
  426.     return rv;
  427. }
  428.  
  429.